package com.chessgame.view;

import com.chessgame.controller.GameController;
import com.chessgame.model.Board;
import com.chessgame.model.Piece;
import com.chessgame.model.PieceType;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;

/**
 * 游戏界面类，负责绘制棋盘和处理用户输入
 */
public class GameView extends JFrame implements GameController.GameStateListener {
    private static final int CELL_SIZE = 60;
    private static final int PIECE_SIZE = 50;
    private static final int BOARD_MARGIN = 40;
    private static final Color BOARD_COLOR = new Color(238, 203, 173);
    private static final Color LINE_COLOR = Color.BLACK;
    private static final Color SELECTED_COLOR = new Color(255, 255, 0, 100);

    private GameController gameController;
    private BoardPanel boardPanel;
    private JLabel statusLabel;
    private JLabel redTimerLabel;
    private JLabel blackTimerLabel;
    private Point selectedPoint;

    public GameView() {
        redTimerLabel = new JLabel("红方用时: 0:00");
        blackTimerLabel = new JLabel("黑方用时: 0:00");
        gameController = new GameController();
        gameController.setGameStateListener(this);
        initializeUI();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            GameView gameView = new GameView();
            gameView.setVisible(true);
        });
    }

    private void initializeUI() {
        setTitle("中国象棋");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());

        // 添加窗口关闭事件处理
        addWindowListener(new java.awt.event.WindowAdapter() {
            @Override
            public void windowClosing(java.awt.event.WindowEvent windowEvent) {
                gameController.cleanup();
            }
        });

        // 创建工具栏
        JToolBar toolBar = new JToolBar();
        toolBar.setFloatable(false);
        JButton newGameButton = new JButton("新游戏");
        JButton undoButton = new JButton("悔棋");
        JButton saveButton = new JButton("保存");
        JButton loadButton = new JButton("读取");
        JButton pauseButton = new JButton("暂停");

        newGameButton.addActionListener(e -> startNewGame());
        undoButton.addActionListener(e -> gameController.undoMove());
        saveButton.addActionListener(e -> saveGame());
        loadButton.addActionListener(e -> loadGame());
        pauseButton.addActionListener(e -> togglePause(pauseButton));

        toolBar.add(newGameButton);
        toolBar.add(undoButton);
        toolBar.add(saveButton);
        toolBar.add(loadButton);
        toolBar.add(pauseButton);

        // 创建状态面板
        JPanel statusPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        statusLabel = new JLabel("红方回合");
        statusPanel.add(statusLabel);
        statusPanel.add(new JSeparator(JSeparator.VERTICAL));
        statusPanel.add(redTimerLabel);
        statusPanel.add(new JSeparator(JSeparator.VERTICAL));
        statusPanel.add(blackTimerLabel);

        // 创建棋盘面板
        boardPanel = new BoardPanel();
        boardPanel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                handleBoardClick(e.getPoint());
            }
        });

        add(toolBar, BorderLayout.NORTH);
        add(boardPanel, BorderLayout.CENTER);
        add(statusPanel, BorderLayout.SOUTH);

        pack();
        setLocationRelativeTo(null);
    }

    private void startNewGame() {
        gameController = new GameController();
        gameController.setGameStateListener(this);
        selectedPoint = null;
        boardPanel.repaint();
        statusLabel.setText("红方回合");
        redTimerLabel.setText("红方用时: 0:00");
        blackTimerLabel.setText("黑方用时: 0:00");
    }

    private void saveGame() {
        JFileChooser fileChooser = new JFileChooser();
        if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
            try {
                gameController.saveGame(fileChooser.getSelectedFile());
                JOptionPane.showMessageDialog(this, "游戏已保存");
            } catch (Exception e) {
                JOptionPane.showMessageDialog(this, "保存失败: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    private void loadGame() {
        JFileChooser fileChooser = new JFileChooser();
        if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
            try {
                gameController.loadGame(fileChooser.getSelectedFile());
                selectedPoint = null;
                boardPanel.repaint();
            } catch (Exception e) {
                JOptionPane.showMessageDialog(this, "加载失败: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    private void togglePause(JButton pauseButton) {
        if (gameController.isPaused()) {
            gameController.resumeGame();
            pauseButton.setText("暂停");
        } else {
            gameController.pauseGame();
            pauseButton.setText("继续");
        }
    }

    private void handleBoardClick(Point point) {
        if (gameController.isPaused()) {
            return;
        }
        
        // 计算点击位置相对于棋盘边缘的偏移
        int offsetX = point.x - BOARD_MARGIN;
        int offsetY = point.y - BOARD_MARGIN;
        
        // 计算最近的格子位置
        int x = Math.round((float)offsetX / CELL_SIZE);
        int y = Math.round((float)offsetY / CELL_SIZE);
        
        // 确保坐标在棋盘范围内
        x = Math.max(0, Math.min(8, x));
        y = Math.max(0, Math.min(9, y));

        if (x < 0 || x >= 9 || y < 0 || y >= 10) {
            return;
        }

        Board board = gameController.getBoard();
        Piece piece = board.getPieceAt(x, y);

        if (selectedPoint == null) {
            if (piece != null && piece.isRed() == board.isRedTurn()) {
                selectedPoint = new Point(x, y);
                boardPanel.repaint();
            }
        } else {
            if (x == selectedPoint.x && y == selectedPoint.y) {
                selectedPoint = null;
                boardPanel.repaint();
            } else {
                // 获取选中的棋子
                Piece selectedPiece = board.getPieceAt(selectedPoint.x, selectedPoint.y);
                
                // 如果是象（相），进行智能模糊判断
                if (selectedPiece != null && 
                    (selectedPiece.getType() == PieceType.RED_ELEPHANT || 
                     selectedPiece.getType() == PieceType.BLACK_ELEPHANT)) {
                    
                    // 计算可能的合法目标位置
                    Point[] possibleMoves = {
                        new Point(selectedPoint.x + 2, selectedPoint.y + 2),
                        new Point(selectedPoint.x + 2, selectedPoint.y - 2),
                        new Point(selectedPoint.x - 2, selectedPoint.y + 2),
                        new Point(selectedPoint.x - 2, selectedPoint.y - 2)
                    };
                    
                    // 找到最近的合法移动位置
                    double minDistance = Double.MAX_VALUE;
                    Point bestMove = null;
                    
                    for (Point move : possibleMoves) {
                        if (move.x >= 0 && move.x < 9 && move.y >= 0 && move.y < 10 &&
                            selectedPiece.isValidMove(board, move.x, move.y)) {
                            double distance = Math.sqrt(
                                Math.pow(move.x - x, 2) + Math.pow(move.y - y, 2)
                            );
                            if (distance < minDistance) {
                                minDistance = distance;
                                bestMove = move;
                            }
                        }
                    }
                    
                    // 如果找到合法的最近位置，使用该位置
                    if (bestMove != null && minDistance < 2.0) {
                        gameController.movePiece(selectedPoint.x, selectedPoint.y, 
                                                bestMove.x, bestMove.y);
                    } else {
                        // 如果没有找到合适的位置，使用原始目标位置
                        gameController.movePiece(selectedPoint.x, selectedPoint.y, x, y);
                    }
                } else {
                    // 其他棋子使用原始移动逻辑
                    gameController.movePiece(selectedPoint.x, selectedPoint.y, x, y);
                }
                
                selectedPoint = null;
                boardPanel.repaint();
            }
        }
    }

    @Override
    public void onBoardUpdate() {
        boardPanel.repaint();
        statusLabel.setText(gameController.getBoard().isRedTurn() ? "红方回合" : "黑方回合");
    }

    @Override
    public void onTimerUpdate(boolean isRed, int seconds) {
        String timeStr = String.format("%d:%02d", seconds / 60, seconds % 60);
        if (isRed) {
            redTimerLabel.setText("红方用时: " + timeStr);
        } else {
            blackTimerLabel.setText("黑方用时: " + timeStr);
        }
    }

    @Override
    public void onGamePaused() {
        statusLabel.setText("游戏已暂停");
    }

    @Override
    public void onGameResumed() {
        statusLabel.setText(gameController.getBoard().isRedTurn() ? "红方回合" : "黑方回合");
    }

    @Override
    public void onCheck(boolean isRedInCheck) {
        String side = isRedInCheck ? "红方" : "黑方";
        statusLabel.setText(side + "被将军!");
    }

    @Override
    public void onGameOver(boolean redWins) {
        String winner = redWins ? "红方" : "黑方";
        statusLabel.setText(winner + "胜利!");
        JOptionPane.showMessageDialog(this, winner + "获胜!", "游戏结束", JOptionPane.INFORMATION_MESSAGE);
    }

    /**
     * 棋盘面板，负责绘制棋盘和棋子
     */
    private class BoardPanel extends JPanel {
        public BoardPanel() {
            setPreferredSize(new Dimension(
                CELL_SIZE * 8 + BOARD_MARGIN * 2,
                CELL_SIZE * 9 + BOARD_MARGIN * 2
            ));
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            // 绘制棋盘背景
            g2d.setColor(BOARD_COLOR);
            g2d.fillRect(0, 0, getWidth(), getHeight());

            // 绘制棋盘网格
            g2d.setColor(LINE_COLOR);
            g2d.setStroke(new BasicStroke(1));

            // 绘制横线
            for (int i = 0; i < 10; i++) {
                g2d.drawLine(
                    BOARD_MARGIN, BOARD_MARGIN + i * CELL_SIZE,
                    BOARD_MARGIN + 8 * CELL_SIZE, BOARD_MARGIN + i * CELL_SIZE
                );
            }

            // 绘制竖线
            for (int i = 0; i < 9; i++) {
                if (i == 0 || i == 8) {
                    g2d.drawLine(
                        BOARD_MARGIN + i * CELL_SIZE, BOARD_MARGIN,
                        BOARD_MARGIN + i * CELL_SIZE, BOARD_MARGIN + 9 * CELL_SIZE
                    );
                } else {
                    // 上半部分
                    g2d.drawLine(
                        BOARD_MARGIN + i * CELL_SIZE, BOARD_MARGIN,
                        BOARD_MARGIN + i * CELL_SIZE, BOARD_MARGIN + 4 * CELL_SIZE
                    );
                    // 下半部分
                    g2d.drawLine(
                        BOARD_MARGIN + i * CELL_SIZE, BOARD_MARGIN + 5 * CELL_SIZE,
                        BOARD_MARGIN + i * CELL_SIZE, BOARD_MARGIN + 9 * CELL_SIZE
                    );
                }
            }

            // 绘制楚河汉界
            g2d.setFont(new Font("宋体", Font.BOLD, 30));
            g2d.drawString("楚河", BOARD_MARGIN + CELL_SIZE, BOARD_MARGIN + 4.7f * CELL_SIZE);
            g2d.drawString("汉界", BOARD_MARGIN + 5 * CELL_SIZE, BOARD_MARGIN + 4.7f * CELL_SIZE);

            // 绘制九宫格斜线
            // 上方九宫格
            g2d.drawLine(
                BOARD_MARGIN + 3 * CELL_SIZE, BOARD_MARGIN,
                BOARD_MARGIN + 5 * CELL_SIZE, BOARD_MARGIN + 2 * CELL_SIZE
            );
            g2d.drawLine(
                BOARD_MARGIN + 5 * CELL_SIZE, BOARD_MARGIN,
                BOARD_MARGIN + 3 * CELL_SIZE, BOARD_MARGIN + 2 * CELL_SIZE
            );
            // 下方九宫格
            g2d.drawLine(
                BOARD_MARGIN + 3 * CELL_SIZE, BOARD_MARGIN + 7 * CELL_SIZE,
                BOARD_MARGIN + 5 * CELL_SIZE, BOARD_MARGIN + 9 * CELL_SIZE
            );
            g2d.drawLine(
                BOARD_MARGIN + 5 * CELL_SIZE, BOARD_MARGIN + 7 * CELL_SIZE,
                BOARD_MARGIN + 3 * CELL_SIZE, BOARD_MARGIN + 9 * CELL_SIZE
            );

            // 绘制棋子
            Board board = gameController.getBoard();
            for (int x = 0; x < 9; x++) {
                for (int y = 0; y < 10; y++) {
                    Piece piece = board.getPieceAt(x, y);
                    if (piece != null) {
                        drawPiece(g2d, piece, x, y);
                    }
                }
            }

            // 绘制选中状态
            if (selectedPoint != null) {
                g2d.setColor(SELECTED_COLOR);
                g2d.fillOval(
                    BOARD_MARGIN + selectedPoint.x * CELL_SIZE - PIECE_SIZE / 2,
                    BOARD_MARGIN + selectedPoint.y * CELL_SIZE - PIECE_SIZE / 2,
                    PIECE_SIZE,
                    PIECE_SIZE
                );
            }
        }

        private void drawPiece(Graphics2D g2d, Piece piece, int x, int y) {
            int centerX = BOARD_MARGIN + x * CELL_SIZE;
            int centerY = BOARD_MARGIN + y * CELL_SIZE;

            // 绘制棋子背景
            g2d.setColor(Color.WHITE);
            g2d.fillOval(centerX - PIECE_SIZE / 2, centerY - PIECE_SIZE / 2, PIECE_SIZE, PIECE_SIZE);
            g2d.setColor(Color.BLACK);
            g2d.setStroke(new BasicStroke(2));
            g2d.drawOval(centerX - PIECE_SIZE / 2, centerY - PIECE_SIZE / 2, PIECE_SIZE, PIECE_SIZE);

            // 绘制棋子文字
            g2d.setFont(new Font("宋体", Font.BOLD, 30));
            g2d.setColor(piece.isRed() ? Color.RED : Color.BLACK);
            g2d.drawString(piece.getType().getDisplayName(), centerX - PIECE_SIZE / 3, centerY + PIECE_SIZE / 3);
        }
    }
}